package Client;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import Billing.Billing;
import Billing.CallOperation;
import Billing.PhoneOperation;
import Billing.SmsOperation;

public class BillingGenerator 
{
	private Double sms_call;
	private Double short_long;
	private Double morning_evening;
	private Random r;
	private Double max_call;
	double[] morning = { 0.5/12.0, 0.1/12.0, 0.1/12.0, 0.1/12.0, 0.1/12.0, 0.1/12.0, 1.0/12.0,
	           1.0/12.0, 2.0/12.0, 2.0/12.0, 2.0/12.0, 3.0/12.0 };

	double[] evening = {3.0/12.0, 2.0/12.0, 2.0/12.0, 2.0/12.0, 1.0/12.0, 1.0/12.0, 0.5/12.0,
	           0.1/12.0,  0.1/12.0, 0.1/12.0, 0.1/12.0, 0.1/12.0};
	
	
	public BillingGenerator(String billing_filename)
	{
		r = new Random();
		max_call = 10800.0;
		readBillingCharacteristics(billing_filename);
	}
	
	public Billing produceBiling(String[] clients_operators)
	{
		Billing billing = new Billing();
		int count = r.nextInt(1000);
		for (int i = 0; i < count; i++)
		{
			//Date time_call = getTimeOfOperation();
			Date time_call = null;
			Boolean sms = getSms();
		    PhoneOperation operation;   
		    String net = getNet(clients_operators);
		    
		    if (sms)
		    	operation = new SmsOperation(null, net);
		    else
		    	operation = new CallOperation(null, net, getLong());
		
		    billing.addOperation(operation);
		}
		return billing;
	}
	
	private void readBillingCharacteristics(String billing_filename) 
	{
		int count = 0;
		int sms = 0;
		int morning = 0;
		int short_calls = 0;
		
		try
		{
			FileInputStream fstream = new FileInputStream(billing_filename);
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;
			while ((strLine = br.readLine()) != null)   
			{
				String[] parts = strLine.split("  ");
			    if (parts.length != 3)
			    	continue;
			    	
			    if (parts[2].equals("sms"))
			    	sms += 1;
			    else
			    	if (Double.valueOf(parts[2]) < 120)
			    		short_calls += 1;
			    
			    count += 1;
			    String[] time = parts[0].split(":");
			    if (Integer.decode(time[0]) < 13)
			    	morning += 1;
			}
			in.close();
		}
		catch (Exception e)
		{
			System.err.println("Error: " + e.getMessage());
		}
		
		this.sms_call = (1.0 * sms) / (1.0 * count);
		this.morning_evening = (1.0 * morning) / (1.0 * count);
		this.short_long = (1.0 * short_calls) / (1.0 * count);
	}
	
	@SuppressWarnings("deprecation")
	private Date getTimeOfOperation()
	{
//	    Double tm = r.nextDouble();
//	    int to_add = 0;
//	    int minutes = r.nextInt(60);
//	  
//	    double[] table;
//	    if (tm < morning_evening)
//	        table = morning;
//	    else
//	    {
//	        table = evening;
//	        to_add = 12;
//	    }
//	        
//	    Double t = r.nextDouble();
//	    Double last = 0.0;
//	    for (int i = 0; i < table.length; i++)
//	    {
//	        if (t < table[i] + last)
//	        	return new Date(0, 0, 0, i + to_add, minutes, 0);
//	        last += table[i];
//	    }
	    
	    //return new Date(0, 0, 0, 12 + to_add, minutes, 0);
		return new Date(0, 0, 0, 0, 0, 0);
	}
	
	private Boolean getSms()
	{
	    Double i = r.nextDouble();
	    if (i < sms_call)
	        return true;
	    else
	        return false;
	}
	
	private Double getLong()
	{
		Double rand = r.nextDouble();
	    Double rr = (rand * short_long) * (rand * short_long); 
	    return rr * max_call;
	}
	
    
	private String getNet(String[] client_operators)
	{
		Integer i = r.nextInt(client_operators.length);
	    return client_operators[i];
	}
}
